#include <QLayout>
#include <QDateTime>

#include <time.h>
#include "timecontrolwidget.h"

TimeControlWidget::TimeControlWidget(QWidget *parent)
: QWidget(parent)
{
    createWidget();
    createConnections();
    this->setMinimumSize(800, 200);
}

void TimeControlWidget::createWidget()
{
    QHBoxLayout* hboxBars = new QHBoxLayout();
    QHBoxLayout* hboxUser = new QHBoxLayout();
    QHBoxLayout* hboxJump = new QHBoxLayout();

    m_btnBarsOnePrev  = new QPushButton("<");
    m_btnBarsOneNext  = new QPushButton(">");
    m_btnBarsManyPrev = new QPushButton("<<");
    m_btnBarsManyNext = new QPushButton(">>");
    m_sliderBarIndex = new QSlider(Qt::Horizontal);
    m_barIndexEdit   = new QLineEdit("");
    m_barIndexEdit->setReadOnly(true);
    hboxBars->addWidget(m_btnBarsOnePrev);
    hboxBars->addWidget(m_btnBarsOneNext);
    hboxBars->addWidget(m_btnBarsManyPrev);
    hboxBars->addWidget(m_btnBarsManyNext);
    hboxBars->addWidget(m_sliderBarIndex);
    hboxBars->addWidget(m_barIndexEdit);

    m_btnUserOnePrev = new QPushButton("<");
    m_btnUserOneNext = new QPushButton(">");
    m_btnUserManyPrev = new QPushButton("<<");
    m_btnUserManyNext = new QPushButton(">>");
    m_sliderUserIndex = new QSlider(Qt::Horizontal);
    m_userIndexEdit   = new QLineEdit("");
    m_userIndexEdit->setReadOnly(true);
    hboxUser->addWidget(m_btnUserOnePrev);
    hboxUser->addWidget(m_btnUserOneNext);
    hboxUser->addWidget(m_btnUserManyPrev);
    hboxUser->addWidget(m_btnUserManyNext);
    hboxUser->addWidget(m_sliderUserIndex);
    hboxUser->addWidget(m_userIndexEdit);

    m_timeEdit = new QLineEdit("2013.12.31");
    m_btnJumpTime = new QPushButton("Jump");
    m_btnSetTime = new QPushButton("Set");
    hboxJump->addWidget(m_timeEdit);
    hboxJump->addWidget(m_btnJumpTime);
    hboxJump->addWidget(m_btnSetTime);

    QVBoxLayout* mainLayout = new QVBoxLayout();
    mainLayout->setMargin(4);
    mainLayout->addLayout(hboxBars);
    mainLayout->addLayout(hboxUser);
    mainLayout->addLayout(hboxJump);
    setLayout(mainLayout);
}

void TimeControlWidget::createConnections()
{
    connect(m_btnJumpTime, SIGNAL(clicked()), this, SLOT(slotJumpButtonClicked()));
    connect(m_btnSetTime, SIGNAL(clicked()), this, SLOT(slotSetButtonClicked()));
    connect(m_btnBarsOnePrev,  SIGNAL(clicked()), this, SLOT(slotBarsOnePrev()));
    connect(m_btnBarsOneNext,  SIGNAL(clicked()), this, SLOT(slotBarsOneNext()));
    connect(m_btnBarsManyPrev, SIGNAL(clicked()), this, SLOT(slotBarsManyPrev()));
    connect(m_btnBarsManyNext, SIGNAL(clicked()), this, SLOT(slotBarsManyNext()));
    connect(m_sliderBarIndex, SIGNAL(valueChanged(int)), this, SLOT(slotBarIndexValueChanged(int)));
    connect(m_btnUserOnePrev,  SIGNAL(clicked()), this, SLOT(slotUserOnePrev()));
    connect(m_btnUserOneNext,  SIGNAL(clicked()), this, SLOT(slotUserOneNext()));
    connect(m_btnUserManyPrev, SIGNAL(clicked()), this, SLOT(slotUserManyPrev()));
    connect(m_btnUserManyNext, SIGNAL(clicked()), this, SLOT(slotUserManyNext()));
    connect(m_sliderUserIndex, SIGNAL(valueChanged(int)), this, SLOT(slotUserIndexValueChanged(int)));
}

void TimeControlWidget::updateBarEdit()
{
    int convertIndex = m_sliderBarIndex->maximum() - m_sliderBarIndex->value();
    m_barIndexEdit->setText(QString::number(convertIndex));
}

void TimeControlWidget::updateUserEdit()
{
    m_userIndexEdit->setText(QString::number(m_sliderUserIndex->value()));
}

time_t TimeControlWidget::updateTimeEdit()
{
    int times = 0;
    QString text = m_timeEdit->text(), strDate, strTime;
    for (int i = 0; i < text.size(); ++i) {
        if (text[i] <= '9' && text[i] >= '0') {
            if (times < 8) {
                strDate[times++] = text[i];
            }
            else if (times < 12) {
                strTime[(times++)-8] = text[i];
            }
        }
    }
    if (strDate.size() < 8)
        strDate = QString("20131231");
    while(strTime.size() < 4) {
        strTime = QString("0000");
    }
    m_timeEdit->setText(strDate+" "+strTime);
    
    QDateTime dataTime = QDateTime::fromString(strDate+strTime,"yyyyMMddhhmm");
    time_t changedDate = dataTime.toTime_t() + 60 * 60 * 8;
    tm *barTime = gmtime(&changedDate);
    char newTime[100];
    sprintf(newTime, "%d.%d.%d %02d:%02d", barTime->tm_year + 1900, barTime->tm_mon + 1, barTime->tm_mday, barTime->tm_hour, barTime->tm_min);
    m_timeEdit->setText(QString(newTime));
    return changedDate;
}

void TimeControlWidget::wheelEvent(QWheelEvent *event)
{
    event->accept();
    int numDegrees = event->delta() / 8;
    if (numDegrees <= 0)
        return;
    int currVal = m_sliderUserIndex->value();
    currVal += numDegrees;
    if (currVal >= m_sliderUserIndex->maximum()) {
        currVal = m_sliderUserIndex->maximum();
    }
    m_sliderUserIndex->setValue(currVal);
}

void TimeControlWidget::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Z || event->key() == Qt::Key_Right) {
        slotBarsOneNext();
    }
    else if (event->key() == Qt::Key_X) {
        slotUserManyNext();
    }
    else if (event->key() == Qt::Key_Left) {
        slotBarsOnePrev();
    }
    else if (event->key() == Qt::Key_B) {
        emit signalBuySignal();
    }
    else if (event->key() == Qt::Key_S) {
        emit signalSellSignal();
    }
}

void TimeControlWidget::slotSetButtonClicked()
{
    time_t changedDate = updateTimeEdit();
    emit signalSetToTime(changedDate);
}

void TimeControlWidget::slotJumpButtonClicked()
{
    time_t changedDate = updateTimeEdit();
    emit signalJumpToTime(changedDate);
}

void TimeControlWidget::slotBarsOnePrev()
{
    m_sliderBarIndex->setValue(m_sliderBarIndex->value() - 1);
}

void TimeControlWidget::slotBarsOneNext()
{
    m_sliderBarIndex->setValue(m_sliderBarIndex->value() + 1);
}

void TimeControlWidget::slotBarsManyPrev()
{
    m_sliderBarIndex->setValue(m_sliderBarIndex->value() - 10);
}

void TimeControlWidget::slotBarsManyNext()
{
    m_sliderBarIndex->setValue(m_sliderBarIndex->value() + 10);
}

void TimeControlWidget::slotUserOnePrev()
{
    m_sliderUserIndex->setValue(m_sliderUserIndex->value() - 1);
}

void TimeControlWidget::slotUserOneNext()
{
    m_sliderUserIndex->setValue(m_sliderUserIndex->value() + 1);
}

void TimeControlWidget::slotUserManyPrev()
{
    m_sliderUserIndex->setValue(m_sliderUserIndex->value() - 15);
}

void TimeControlWidget::slotUserManyNext()
{
    m_sliderUserIndex->setValue(m_sliderUserIndex->value() + 15);
}

void TimeControlWidget::slotSetHistIndexRange(int minVal, int maxVal)
{
    m_sliderBarIndex->blockSignals(true);
    m_sliderBarIndex->setMinimum(minVal);
    m_sliderBarIndex->setMaximum(maxVal);
    m_sliderBarIndex->setValue(maxVal);
    updateBarEdit();
    m_sliderBarIndex->blockSignals(false);
}

void TimeControlWidget::slotBarIndexValueChanged(int index)
{
    updateBarEdit();
    int convertIndex = m_sliderBarIndex->maximum() - m_sliderBarIndex->value();
    emit signalBarIndexChanged(convertIndex);
}

void TimeControlWidget::slotSetHisIndex(int index)
{
    m_sliderBarIndex->setValue(m_sliderBarIndex->maximum() - index);
}

void TimeControlWidget::slotChangedHisIndex(int index)
{
    m_sliderBarIndex->blockSignals(true);
    m_sliderBarIndex->setValue(m_sliderBarIndex->maximum() - index);
    updateBarEdit();
    m_sliderBarIndex->blockSignals(false);
}

void TimeControlWidget::slotSetUserIndexRange(int minVal, int maxVal)
{
    m_sliderUserIndex->blockSignals(true);
    m_sliderUserIndex->setMinimum(minVal);
    m_sliderUserIndex->setMaximum(maxVal);
    m_sliderUserIndex->setValue(minVal);
    updateUserEdit();
    m_sliderUserIndex->blockSignals(false);
}

void TimeControlWidget::slotSetUserIndex(int index)
{
    m_sliderUserIndex->setValue(m_sliderUserIndex->maximum() - index);
}

void TimeControlWidget::slotChangedUserIndex(int index)
{
    m_sliderUserIndex->blockSignals(true);
    m_sliderUserIndex->setValue(m_sliderUserIndex->maximum() - index);
    updateUserEdit();
    m_sliderUserIndex->blockSignals(false);
}

void TimeControlWidget::slotUserIndexValueChanged(int index)
{
    updateUserEdit();
    int convertIndex = m_sliderUserIndex->maximum() - m_sliderUserIndex->value();
    emit signalUserIndexChanged(convertIndex);
}